<!--
 * @Description: 
 * @Author: duan_shuangjun 丶
 * @Date: 2025-09-03 16:40:55
 * @LastEditTime: 2025-10-12 22:05:26
-->
<!--
 * @Description: 
 * @Author: duan_shuangjun 丶
 * @Date: 2025-09-03 16:40:55
 * @LastEditTime: 2025-09-03 22:51:34
-->
<template>
  <div>
    <div class="book-content-wrap">
      <div class="left-box" :class="{ fullWidth: selectBookData ? false : true }">
        <div class="left-srcoll-wrap">
          <div class="search-select-box">
            <div class="search-content">
              <div class="datetimerange-type-box">
                <el-date-picker
                  class="select"
                  v-model="deskBookPagePramas.day"
                  type="date"
                  placeholder="选择日期"
                  value-format="yyyy-MM-dd"
                  style="width: 1.4rem"
                  @change="onSearch"
                >
                </el-date-picker>
                <div class="refund-type">
                  <div class="desc">班次</div>
                  <el-select
                    v-model="deskBookPagePramas.time_slot"
                    class="select"
                    @change="onSearch"
                    placeholder="请选择班次"
                    clearable
                  >
                    <el-option
                      v-for="item in shiftTypeOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </div>
              </div>
              <div class="search-input-box" v-show="isChangeShow">
                <img class="search-icon" src="@/assets/images/home/search-icon.png" alt="" />
                <input
                  class="input"
                  v-model="deskListPagePramas.name"
                  type="text"
                  placeholder="搜索桌台号（回车查询）"
                  @keyup.enter="onSearch"
                />
              </div>
              <div class="search-input-box" v-show="!isChangeShow">
                <img class="search-icon" src="@/assets/images/home/search-icon.png" alt="" />
                <input
                  class="input"
                  v-model="deskBookPagePramas.search"
                  type="text"
                  placeholder="搜索顾客姓名/电话（回车查询）"
                  @keyup.enter="onSearch"
                />
              </div>
            </div>
            <div class="tag-select-box" v-show="!isChangeShow">
              <div class="tag-btn-list">
                <div
                  class="tag-btn-item"
                  :class="{ 'tag-btn-item-active': tagActiveIndex === tagIndex }"
                  @click="handleSelectTag(tagIndex, tagItem.status)"
                  v-for="(tagItem, tagIndex) in tagButtonList"
                  :key="tagItem.name + tagIndex"
                >
                  {{ tagItem.name }}
                </div>
              </div>
            </div>
            <!-- <div class="book-date-list"> -->
          </div>
          <!-- 列表内容区域 -->
          <div class="book-list-wrap" :class="{ contentFullWidth: selectBookData ? false : true }">
            <!-- 桌台列表相关组件 -->
            <BookDeskTopList
              v-show="isChangeShow"
              :filters="{
                day: deskBookPagePramas.day,
                time_slot: deskBookPagePramas.time_slot,
                name: deskListPagePramas.name
              }"
              @onDoubleSelect="onDoubleSelectDesk"
              ref="BookDeskTopList"
            />
            <!-- 预订列表组件 -->
            <BookTableList
              :bookDeskPageList="bookDeskPageList"
              v-show="!isChangeShow"
              :loading="listLoading"
              @rowSelected="onRowSelected"
              ref="BookTableList"
            />
            <div class="desktop-count-box" v-if="!isChangeShow">
              <div class="left">共{{ pageTotal }}条</div>
              <div class="right" v-show="!isChangeShow">
                <Pagination
                  :total="pageTotal"
                  v-model:page="deskBookPagePramas.page"
                  v-model:limit="deskBookPagePramas.limit"
                  @pagination="getDeskBookList"
                />
              </div>
              <!-- 桌台列表分页由子组件内部处理，不再在父级渲染 -->
            </div>
          </div>
        </div>
        <!-- 操作按钮 -->
        <div class="left-action-wrap" :class="{ btnListFullWidth: selectBookData ? false : true }">
          <div class="button-list">
            <div
              class="button-item"
              :class="{ 'button-disabled': isButtonDisabled(index) }"
              @click="handleAction(index)"
              v-for="(item, index) in actionsList"
              :key="item.name + index"
              :style="{ borderColor: buttonColorEnum[index] ? buttonColorEnum[index] : '#333' }"
            >
              <img
                v-if="index === 3"
                class="change-image"
                src="@/assets/images/qiehuan-icon.png"
                alt=""
              />
              <span :style="{ color: buttonColorEnum[index] ? buttonColorEnum[index] : '#333' }">{{
                item.name
              }}</span>
            </div>
          </div>
        </div>
      </div>
      <div class="right-box" v-if="selectBookData">
        <!-- 充值单卡片组件 -->
        <BillCard :selectedBookData="selectBookData" />
      </div>
    </div>
    <!-- 短信记录的弹窗组件 -->
    <ShortMessageRecordDialog v-model="dialogData.showShortMessageRecordDialog" />
    <!-- 新增or编辑预订的弹窗组件 -->
    <BookCreateDialog
      v-model="dialogData.showBookCreateDialog"
      @onConfirmSuccess="getBookList"
      :actionType="actionType"
      :editData="selectBookData"
    />
    <!-- 定金发票的弹窗组件 -->
    <DepositInvoiceDialog
      v-model="dialogData.showDepositInvoiceDialog"
      :selectedBookData="selectBookData"
    />
  </div>
</template>

<script>
import BillCard from './components/BillCard.vue'
import BookDeskTopList from './components/BookDeskTopList.vue'
import BookTableList from './components/BookTableList.vue'
import ShortMessageRecordDialog from './components/ShortMessageRecordDialog.vue'
import BookCreateDialog from './components/BookCreateDialog.vue'
import DepositInvoiceDialog from './components/DepositInvoiceDialog.vue'
import Pagination from '@/components/Pagination/Index.vue'
import {
  deskBookList,
  bookDeskTopList,
  deskBookCancel,
  deskBookMessageSend,
  deskBookOpenBookDesk
} from '@/api/book'
import messageTips from '@/components/messageTips/index'
import { useUserStore } from '@/stores/user'
import {
  filterObjectEmptyAttribute,
  isEmpty,
  debounce,
  dealAssignDataFunction
} from '@/utils/toolsValidate'
import { fetchCategoryList } from '@/api/desktop'
import { LocalStorage } from '@/utils/storage'
import { getNowDateAndTime } from '@/utils/index'
// 预订页面操作按钮列表（本地定义，替代外部常量）
export default {
  name: 'BookIndex',
  components: {
    BillCard,
    BookDeskTopList,
    BookTableList,
    ShortMessageRecordDialog,
    BookCreateDialog,
    DepositInvoiceDialog,
    Pagination
  },
  data() {
    return {
      // 左侧操作按钮（顺序需与旧版一致）
      actionsListData: [
        { name: '新增预订' },
        { name: '修改预订' },
        { name: '取消预订' },
        { name: '桌台列表' },
        { name: '预订菜品' },
        { name: '预订开台' },
        { name: '发送短信' },
        { name: '短信记录' },
        { name: '定金发票' }
        // { name: '导出' }
      ],
      // 列表loading
      listLoading: false,
      // 本地选中的预订行数据（替代 vuex）
      selectedBookData: null,
      // 班次类型枚举列表
      shiftTypeOptions: [
        { label: '全天', value: 'all' },
        { label: '早上', value: 'early_time' },
        { label: '中午', value: 'midday_time' },
        { label: '下午', value: 'afternoon_time' },
        { label: '晚上', value: 'night_time' }
      ],
      // 是否显示对应弹窗相关判断数据
      dialogData: {
        showShortMessageRecordDialog: false,
        showBookCreateDialog: false,
        showDepositInvoiceDialog: false
      },
      // 预订列表相关参数
      deskBookPagePramas: {
        page: 1,
        limit: 10,
        search: '',
        status: 0,
        day: '',
        time_slot: 'all'
      },
      // 标签按钮列表
      tagButtonList: [
        { name: '全部', status: 0 },
        { name: '正常', status: 1 },
        { name: '已开台', status: 2 },
        { name: '已结束', status: 3 },
        { name: '已过期', status: 4 }
      ],
      // 标签按钮点击选中索引下标
      tagActiveIndex: 0,
      // 切换桌台列表和预订列表
      isChangeShow: false,
      // 预订列表
      bookDeskPageList: [],
      // 分页列表总条数
      pageTotal: 0,
      // 预订桌台列表相关分页参数
      deskListPagePramas: {
        page: 1,
        limit: 10,
        name: '',
        status: 0,
        day: '',
        time_slot: 'all',
        category_id: ''
      },
      // 预订桌台列表
      deskTopBookPageList: [],
      // 桌台分类列表
      deskCategoryList: [],
      // 桌台分类列表分页相关
      deskCategoryPageQuery: {
        page: 1,
        limit: 5
      },
      // 判断一级分类是否还能继续下一页操作分页
      deskOneCategoryLastPage: 0,
      // 区分操作类型，编辑还是新增
      actionType: '',
      // 按钮颜色枚举
      buttonColorEnum: {
        0: '#67c23a',
        1: '#E6A23C',
        2: '#7c0a03'
      }
    }
  },
  mounted() {
    try {
      const userStore = useUserStore()
      userStore.initLoadUserProfile && userStore.initLoadUserProfile()
      this._userStore = userStore
    } catch (e) {}
    this.getDeskBookList()
    
    // 检查是否从点菜页面返回，如果是则打开预订弹框
    this.checkReturnFromFoodOrder()
  },

  computed: {
    // 替代 vuex：使用本地选中数据
    selectBookData() {
      return this.selectedBookData
    },
    // 预订的操作按钮相关列表
    actionsList() {
      this.actionsListData.forEach((item, index) => {
        if (index === 3) {
          item.name = this.isChangeShow ? '预订列表' : '桌台列表'
        }
      })
      return this.actionsListData
    }
  },
  methods: {
    // 检查是否从点菜页面返回
    checkReturnFromFoodOrder() {
      const bookDialogData = sessionStorage.getItem('bookDialogData')
      if (bookDialogData) {
        try {
          const data = JSON.parse(bookDialogData)
          if (data) {
            // 延迟打开弹框，确保组件已完全挂载
            this.$nextTick(() => {
              this.dialogData.showBookCreateDialog = true
            })
            this.actionType = data.book_id ? 'edit' : 'add'
          }
        } catch (error) {
          console.error('解析返回数据失败:', error)
          sessionStorage.removeItem('bookDialogData')
        }
      }
    },
    // 双击桌台，打开新增预订弹窗
    onDoubleSelectDesk() {
      this.actionType = 'add'
      this.dialogData.showBookCreateDialog = true
    },
    // 搜索操作
    onSearch: debounce(function () {
      if (this.isChangeShow) {
        this.resetDeskTopList()
      } else {
        this.resetBookDeskTopList()
      }
    }, 500),
    // 选中对应的筛选预订列表状态
    handleSelectTag(index, status) {
      this.tagActiveIndex = index
      this.deskBookPagePramas.status = status
      this.deskBookPagePramas.page = 1
      // 显示预订列表数据
      this.getDeskBookList()
    },
    getBookList() {
      this.$nextTick(() => {
        LocalStorage.set('bookId', '')
      })
      this.getDeskBookList()
    },
    // 获取预订列表数据
    getDeskBookList() {
      this.listLoading = true
      deskBookList(filterObjectEmptyAttribute(this.deskBookPagePramas))
        .then(res => {
          if (res.status === 200) {
            this.bookDeskPageList = dealAssignDataFunction([], res?.data?.list?.data)
            this.pageTotal = dealAssignDataFunction(0, res?.data?.list?.total)
          }
        })
        .finally(() => {
          this.listLoading = false
        })
    },
    // 获取预订页面的桌台列表数据
    // 重置预订列表相关数据
    resetBookDeskTopList() {
      this.tagActiveIndex = 0
      this.deskBookPagePramas.page = 1
      this.deskBookPagePramas.status = 0
      // 显示预订列表数据
      this.getDeskBookList()
    },
    // 重置预订桌台列表相关数据（已内聚到子组件，仅切换时调用其内部逻辑）
    resetDeskTopList() {},

    // 点击对应的操作栏按钮
    async handleAction(index) {
      // 如果按钮被置灰，直接返回不执行任何操作
      if (this.isButtonDisabled(index)) {
        return
      }

      // 切换预订列表和桌台列表
      if (index === 3) {
        this.isChangeShow = !this.isChangeShow
        // 显示桌台列表
        if (this.isChangeShow) {
          this.deskListPagePramas = {
            page: 1,
            limit: 10,
            name: '',
            status: 0,
            day: '',
            time_slot: 'all',
            category_id: ''
          }
          this.resetDeskTopList()
          this.deskCategoryPageQuery = {
            page: 1,
            limit: 5
          }
          // 获取桌台分类数据
          this.getDesktopCategoryList()
        } else {
          this.deskBookPagePramas = {
            page: 1,
            limit: 10,
            search: '',
            status: 0,
            day: '',
            time_slot: 'all'
          }
          this.resetBookDeskTopList()
        }
        return
      }
      // 先判断是否选中了对应的预订id
      const ACTION_MAP = {
        4: '预订菜品',
        1: '修改预订',
        2: '取消预订',
        5: '预订开台',
        6: '发送短信',
        8: '定金发票',
        9: '导出'
      }
      if (ACTION_MAP[index] && isEmpty(this.selectBookData)) {
        this.$message.warning('请先选择对应的预订订单')
        return
      }
      if (ACTION_MAP[index] && this.selectBookData.status.value === 4) {
        this.$message.error('当前预订已过期')
        return
      }
      if (ACTION_MAP[index] && index !== 4 && this.selectBookData.status.value === 3) {
        this.$message.error('当前预订已结束或已取消')
        return
      }
      if ([1, 2, 4, 5].includes(index) && this.selectBookData.status.value === 2) {
        this.$message.error('当前预订已开台')
        return
      }
      // 打开预订菜品页面
      if (index === 4) {
        // 跳转点菜页面
        this.$router.push({
          name: 'FoodOrder',
          params: { id: this.selectBookData?.desk_id || '1' },
          query: {
            fromPage: 'appointmentPage',
            actionType: 'bookFood',
            bookId: this.selectBookData?.id // 传递预约ID
          }
        })
        return
      }
      // 新增预订
      if (index === 0) {
        this.actionType = 'add'
        this.dialogData.showBookCreateDialog = true
        return
      }
      // 修改预订
      if (index === 1) {
        this.actionType = 'edit'
        this.dialogData.showBookCreateDialog = true
        return
      }
      // 取消预订
      if (index === 2) {
        if (!this.selectBookData) return
        // 使用新消息函数进行纯文字确认
        const userName = this.selectBookData?.user_name || ''
        const messageInstance = await messageTips.message(
          {
            title: '取消预订',
            content: `确定取消“${userName}”的预订订单吗？`,
            isOnCancel: true,
            onCancelText: '取消',
            onSumbitText: '确认'
          },
          async () => {
            try {
              messageInstance.setLoading(true)
              const params = { book_id: this.selectBookData.id }
              const res = await deskBookCancel(params)
              if (res?.status === 200) {
                this.$message.success('已取消预订')
                this.getDeskBookList()
              }
            } finally {
              messageInstance.setLoading(false)
              messageInstance.close && messageInstance.close()
            }
          }
        )
        return
      }
      // 预订开台
      if (index === 5) {
        if (!this.selectBookData) return
        const userName = this.selectBookData?.user_name || ''
        const messageInstance = await messageTips.message(
          {
            title: '预订开台',
            content: `确定对“${userName}”的预订进行开台吗？`,
            isOnCancel: true,
            onCancelText: '取消',
            onSumbitText: '确认'
          },
          async () => {
            try {
              messageInstance.setLoading(true)
              const params = { book_id: this.selectBookData.id }
              const res = await deskBookOpenBookDesk(params)
              if (res?.status === 200) {
                this.$message.success('开台成功')
                this.getDeskBookList()
              }
            } finally {
              messageInstance.setLoading(false)
              messageInstance.close && messageInstance.close()
            }
          }
        )
        return
      }
      // 发送短信
      if (index === 6) {
        if (!this.selectBookData) return
        const shopName = (this._userStore && this._userStore.shopInfo?.shop_name) || ''
        const bookTimeText =
          this.selectBookData?.book_time?.text || this.selectBookData?.book_time || ''
        const messageInstance = await messageTips.message(
          {
            title: '发送短信',
            content: `【${shopName}】您预订了${bookTimeText}的就餐时间，请注意时间前往就餐`,
            isOnCancel: true,
            onCancelText: '取消',
            onSumbitText: '发送'
          },
          async () => {
            try {
              messageInstance.setLoading(true)
              const params = { book_id: this.selectBookData.id }
              const res = await deskBookMessageSend(params)
              if (res?.status === 200) {
                this.$message.success('短信发送成功')
              }
            } finally {
              messageInstance.setLoading(false)
              messageInstance.close && messageInstance.close()
            }
          }
        )
        return
      }
      // 短信记录
      if (index === 7) {
        return (this.dialogData.showShortMessageRecordDialog = true)
      }
      // 定金发票
      if (index === 8) {
        // 检查定金金额是否为0
        const bookMoney = this.selectBookData?.book_money || 0
        if (bookMoney <= 0) {
          this.$message.warning('定金金额为0，没法开票')
          return
        }
        return (this.dialogData.showDepositInvoiceDialog = true)
      }
    },
    // 列表选中回调
    onRowSelected(row) {
      this.selectedBookData = row
      // 同步缓存ID，兼容其他组件读取
    },
    // 判断按钮是否应该置灰
    isButtonDisabled(index) {
      // 新增预订、桌台列表、短信记录、导出 不需要选中数据
      if ([0, 3, 7, 9].includes(index)) {
        return false
      }
      // 其他按钮都需要选中数据才能点击
      return !this.selectBookData
    }
  }
}
</script>
<style lang="scss" scoped>
::v-deep {
  .el-input__inner {
    border-radius: 12px;
  }
}
.fullWidth {
  width: 1600px !important;
}
.contentFullWidth {
  width: 1400px !important;
}

.btnListFullWidth {
  width: 250px !important;
}
.book-content-wrap {
  display: flex;
  align-items: flex-start;
  .left-box {
    box-sizing: border-box;
    width: 1284px;
    height: 890px;
    background: #ffffff;
    border-radius: 20px;
    box-shadow: 3px 0px 24px 0px rgba(0, 0, 0, 0.16);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    .left-srcoll-wrap {
      box-sizing: border-box;
      .search-select-box {
        background: #ffffff;
        border-radius: 20px 20px 0px 0px;
        box-sizing: border-box;
        padding: 20px 30px;
        .search-content {
          display: flex;
          align-items: center;
          justify-content: space-between;
          .datetimerange-type-box {
            display: flex;
            align-items: center;
            .refund-type {
              display: flex;
              align-items: center;
              margin-left: 20px;
              .desc {
                font-size: 16px;
                font-family:
                  PingFang SC,
                  PingFang SC-Regular;
                font-weight: 400;
                text-align: left;
                color: #333333;
                margin-right: 20px;
              }
              .select {
                width: 200px;
              }
            }
          }
          .search-input-box {
            width: 242px;
            height: 40px;
            border: 1px solid #d2d2d2;
            border-radius: 25px;
            box-sizing: border-box;
            display: flex;
            align-items: center;
            padding-left: 20px;
            .search-icon {
              flex-shrink: 0;
              width: 24px;
              height: 24px;
            }
            .input {
              border: none;
              outline: none;
              width: 160px;
              font-size: 16px;
              font-family:
                PingFang SC,
                PingFang SC-Regular;
              font-weight: 400;
              text-align: left;
              color: #333;
              margin-left: 10px;
            }
          }
        }
      }
      .tag-select-box {
        margin-top: 20px;
        padding-bottom: 10px;
        .tag-btn-list {
          display: flex;
          align-items: center;

          .tag-btn-item {
            width: 96px;
            height: 40px;
            line-height: 40px;
            border: 1px solid #d2d2d2;
            border-radius: 12px;
            font-size: 16px;
            font-family:
              PingFang SC,
              PingFang SC-Regular;
            font-weight: 400;
            text-align: center;
            color: #666666;
            cursor: pointer;
            margin-right: 20px;
          }

          .tag-btn-item-active {
            border-color: #7c0a03 !important;
            color: #7c0a03 !important;
          }
        }

        .tag-status-list {
          display: flex;
          align-items: center;

          .tag-status-item {
            display: flex;
            align-items: center;
            margin-right: 20px;

            .circular {
              width: 14px;
              height: 14px;
              border-radius: 50%;
              margin-right: 12px;
            }

            .name {
              font-size: 14px;
              font-family:
                PingFang SC,
                PingFang SC-Regular;
              font-weight: 400;
            }
          }

          .tag-status-item:last-child {
            margin-right: 0;
          }
        }
      }
      .book-list-wrap {
        width: 1104px;
        height: 776px;
        border-radius: 0px 0px 0px 20px;
        .desktop-count-box {
          height: 60px;
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding: 0 30px;

          .left {
            font-size: 14px;
            font-family:
              PingFang SC,
              PingFang SC-Regular;
            font-weight: 400;
            color: #333333;
          }
        }
      }
    }
    .left-action-wrap {
      width: 180px;
      height: 890px;
      background: #ffffff;
      border-radius: 0px 20px 20px 0px;
      box-sizing: border-box;
      border-left: 1px solid #f4f4f4;
      padding: 50px 0;
      .button-list {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: space-between;
        height: 100%;
        .button-item {
          min-width: 120px;
          height: 48px;
          line-height: 48px;
          border: 1px solid #333333;
          border-radius: 12px;
          font-size: 18px;
          font-family:
            PingFang SC,
            PingFang SC-Regular;
          font-weight: 400;
          text-align: center;
          color: #333333;
          cursor: pointer;
          display: flex;
          align-items: center;
          justify-content: center;
          .change-image {
            width: 16px;
            height: 16px;
            flex-shrink: 0;
            margin-right: 10px;
          }
        }
        .button-item:hover {
          border-color: rgb(124, 10, 3);
          color: rgb(124, 10, 3);
        }
        .button-item.button-disabled {
          opacity: 0.5;
          cursor: not-allowed;
          border-color: #ccc !important;
          color: #999 !important;
        }
        .button-item.button-disabled:hover {
          border-color: #ccc !important;
          color: #999 !important;
        }
      }
    }
  }
  .right-box {
    margin-left: 30px;
  }
}
</style>
